package com.mobile.zlb.service.impl;


import com.alibaba.fastjson.JSONObject;
import com.mobile.zlb.domain.ClientZlb;
import com.mobile.zlb.mapper.ClientZlbMapper;
import com.mobile.zlb.model.ZlbClientInfo;
import com.mobile.zlb.model.ZlbTicketClientInfo;
import com.mobile.zlb.service.IZlbClientService;
import com.mobile.zlb.utils.HmacAuthUtil;
import com.mobile.zlb.utils.HttpUtil;
import com.ruoyi.common.constant.ZlbConstants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.sign.Md5Utils;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.system.mapper.SysRoleMapper;
import org.apache.http.client.methods.HttpPost;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 浙里办用户认证Service
 *
 * @author mobile
 * @date 2022/4/14
 */
@Service
public class ZlbClientServiceImpl implements IZlbClientService {

    /**
     * token验证处理
     */
    @Resource
    private TokenService tokenService;
    /**
     * 用户角色表处理
     */
    @Resource
    private SysRoleMapper sysRoleMapper;

    @Autowired
    private ClientZlbMapper clientZlbMapper;

    /**
     * 浙里办应用标识&应用密钥（仅正式ak和sk，没有测试环境）
     */
    @Value("${zlb.appKey}")
    private String APP_KEY;
    @Value("${zlb.appSecret}")
    private String APP_SECRET;

    /**
     * 接口请求
     */
    private final HttpUtil httpUtil = HttpUtil.getInstance();
    /**
     * 日志打印
     */
    private static final Logger logger = LoggerFactory.getLogger(ZlbClientServiceImpl.class);

    /**
     * 票据认证
     *
     * @param ticket 票据
     * @return
     */
    @Override
    public AjaxResult getClientTicketCode(String ticket) {
        // 票据认证（IF 测试环境，ELSE 真实环境）
        if (ZlbConstants.MSG_INFO_APP_TEST_CODE.equals(ticket)) {
            SysUser sysUser = new SysUser();
            sysUser.setUserId(1L);
            sysUser.setNickName("测试人");
            sysUser.setUserName("测试人");
            //设置用户角色-默认全部角色
            List<SysRole> roles = sysRoleMapper.selectRoleAll();
            sysUser.setRoles(roles);
            // 设置用户鉴权的用户信息
            LoginUser loginUser = new LoginUser();
            loginUser.setUser(sysUser);
            Set<String> permissions = new HashSet<>();
            // 设置用户权限-默认全部权限
            permissions.add("*.*.*");
            loginUser.setPermissions(permissions);
            // 生成token
            ZlbClientInfo clientInfo = new ZlbClientInfo();
            clientInfo.setUserName("*测试");
            clientInfo.setSign(tokenService.createToken(loginUser));
            return AjaxResult.success(clientInfo);
        } else {
            String url = "https://ibcdsg.zj.gov.cn:8443/restapi/prod/IC33000020220228000002/sso/servlet/simpleauth";
            // 接口请求方法
            String method = "POST";
            // 封装请求参数
            Map<String, String> header = HmacAuthUtil.generateHeader(url, method, APP_KEY, APP_SECRET);
            // 创建POST请求
            HttpPost httpPost = new HttpPost(url);
            Iterator<String> its = header.keySet().iterator();
            while (its.hasNext()) {
                String next = its.next();
                httpPost.addHeader(next, header.get(next));
            }
            // 拼接请求参数
            Map<String, String> params = new HashMap<String, String>(12);
            String time = getSecondTimestamp();
            params.put("servicecode", APP_KEY);
            params.put("method", "ticketValidation");
            // 时间戳，当前时间
            params.put("time", time);
            // MD5(servicecode+servicepwd+time)参数servicepwd为组件平台的SecretKey
            params.put("sign", Md5Utils.hash(APP_KEY + APP_SECRET + time));
            // 票据
            params.put("st", ticket);
            // 返回数据类型
            params.put("datatype", "json");
            String result = httpUtil.sendHttpPost(httpPost, params);
            logger.info("浙里办用户认证接口请求结果：" + result);
            JSONObject resultJson = JSONObject.parseObject(result);
            // 请求结果
            String resultCode = resultJson.getString("result");
            if (ZlbConstants.MSG_INFO_ZLB_STATUS_SUCCESS.equals(resultCode)) {
                // 获取票据的用户信息
                ZlbTicketClientInfo ticketClientInfo = JSONObject.parseObject(result, ZlbTicketClientInfo.class);
                logger.info("浙里办用户认证接口----------ZlbClientInfo：" + ticketClientInfo.toString());
                // 令牌
                String token = resultJson.getString("token");
                // 用户在SSO分配的身份唯一号
                String userid = resultJson.getString("userid");
                // 登录的用户名
                String loginname = resultJson.getString("loginname");
                // 用户姓名
                String username = resultJson.getString("username");
                logger.info("浙里办用户认证接口----------用户姓名：" + username);
                // 检查本地系统是否录入该用户
                ClientZlb clientZlb = new ClientZlb();
                // 设置浙里办的唯一主键
                clientZlb.setZlbUserId(userid);
                List<ClientZlb> clientZlbList = clientZlbMapper.selectClientZlbList(clientZlb);
                // 用户认证信息
                SysUser sysUser = new SysUser();
                // 将用户录入本地系统
                if (clientZlbList.isEmpty()) {
                    // 登录账号
                    clientZlb.setUserName(loginname);
                    // 用户姓名
                    clientZlb.setNickName(username);
                    // 创建人
                    clientZlb.setCreateBy(ZlbConstants.MSG_INFO_APP_OPERATER);
                    clientZlb.setLoginDate(new Date());
                    int row = clientZlbMapper.insertClientZlb(clientZlb);
                    // 插入浙里办用户至本地数据库
                    if (row == 1) {
                        // 设置用户主键
                        sysUser.setUserId(clientZlbMapper.selectClientZlbByZlbUserId(userid).getUserId());
                    } else {
                        sysUser.setUserId(1L);
                        logger.error("错误，无法完成浙里办用户认证" + username + "||" + userid);
                    }
                } else {
                    sysUser.setUserId(clientZlbList.get(0).getUserId());
                    // 更新本地用户最后登录时间
                    clientZlb.setUserId(clientZlbList.get(0).getUserId());
                    clientZlb.setLoginDate(new Date());
                    clientZlbMapper.updateClientZlb(clientZlb);
                }
                sysUser.setNickName(username);
                sysUser.setUserName(username);
                // 设置用户鉴权的用户信息
                LoginUser loginUser = new LoginUser();
                loginUser.setUser(sysUser);
                Set<String> permissions = new HashSet<>();
                // 设置用户权限-默认全部权限
                permissions.add("*.*.*");
                loginUser.setPermissions(permissions);
                // 用户身份认证标识
                ticketClientInfo.setSign(tokenService.createToken(loginUser));
                // 用户身份令牌（浙里办）
                ticketClientInfo.setToken(token);
                // 用户姓名脱敏
                ticketClientInfo.setUserName("*" + username.substring(1));
                return AjaxResult.success(ticketClientInfo);
            }
            return AjaxResult.error(resultCode);
        }
    }

    @Override
    public AjaxResult getClientInfoByToken(String token) {
        String url = "https://ibcdsg.zj.gov.cn:8443/restapi/prod/IC33000020220228000004/sso/servlet/simpleauth";
        // 接口请求方法
        String method = "POST";
        // 封装请求参数
        Map<String, String> header = HmacAuthUtil.generateHeader(url, method, APP_KEY, APP_SECRET);
        // 创建POST请求
        HttpPost httpPost = new HttpPost(url);
        Iterator<String> its = header.keySet().iterator();
        while (its.hasNext()) {
            String next = its.next();
            httpPost.addHeader(next, header.get(next));
        }
        // 拼接请求参数
        Map<String, String> params = new HashMap<String, String>(12);
        String time = getSecondTimestamp();
        params.put("servicecode", APP_KEY);
        params.put("method", "getUserInfo");
        // 时间戳，当前时间
        params.put("time", time);
        // MD5(servicecode+servicepwd+time)参数servicepwd为组件平台的SecretKey
        params.put("sign", Md5Utils.hash(APP_KEY + APP_SECRET + time));
        // 票据
        params.put("token", token);
        // 返回数据类型
        params.put("datatype", "json");
        String result = httpUtil.sendHttpPost(httpPost, params);
        logger.info("浙里办用户认证接口请求结果：" + result);
        JSONObject resultJson = JSONObject.parseObject(result);
        // 请求结果
        String resultCode = resultJson.getString("result");
        if (ZlbConstants.MSG_INFO_ZLB_STATUS_SUCCESS.equals(resultCode)) {
            // 根据token获取用户信息
            ZlbClientInfo zlbClientInfo = JSONObject.parseObject(result, ZlbClientInfo.class);
            logger.info("根据token获取用户信息ZlbClientInfo：" + zlbClientInfo.toString());
            return AjaxResult.success(zlbClientInfo);
        }
        return AjaxResult.error(resultCode);
    }

    /**
     * 获取时间戳，当前时间(年月日时分秒)
     *
     * @return 时间戳，当前时间(年月日时分秒)例如：2009年10月10日 12时12分12秒格式为20091010121212
     */
    private static String getSecondTimestamp() {
        // 时间戳，当前时间(年月日时分秒)
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
        return formatter.format(new Date());
    }

}
